#ifndef _MESSAGETEST_
#define _MESSAGETEST_
#include "client.h"
#include "connectionlistener.h"
#include "registration.h"
#include "logsink.h"
#include "loghandler.h"
#include "MessageSessionHandler.h"
#include "MessageEventHandler.h"
#include "MessageHandler.h"
#include "ChatStateHandler.h"
#include "MessageEventFilter.h"
#include "ChatStateFilter.h"
#include "RosterManager.h"
#include "Disco.h"
#include "message.h"
#include "flogger.h"
#include "strutil.h"
using namespace gloox;

class MessageTest : public MessageSessionHandler, ConnectionListener, LogHandler,
                    MessageEventHandler, MessageHandler, ChatStateHandler
{
  public:
    MessageTest() : m_session( 0 ), m_messageEventFilter( 0 ), m_chatStateFilter( 0 ) {}

    virtual ~MessageTest() 
    	{
    	j->disposeMessageSession( m_session );
    	delete m_messageEventFilter;
    	delete m_chatStateFilter;
    	delete j;
    	j=0;
    	iLog.CloseLog(); 
    	iLog.Close(); 
    	}

    void start()
    {
    	iLog.Connect(); 
    	iLog.CreateLog(_L("xmpp"),_L("xmpplog.txt"),EFileLoggingModeOverwrite); 
      JID jid;
      jid.setUsername( "zlj200427@sina.com" );
      jid.setServer("talk.xiaonei.com");
      j = new Client( jid, "198412027" );
      j->registerConnectionListener( this );
      j->registerMessageSessionHandler( this, 0 );
      j->disco()->setVersion( "messageTest", GLOOX_VERSION, "Symbian" );
      j->disco()->setIdentity( "client", "bot" );
      j->disco()->addFeature( XMLNS_CHAT_STATES );
      j->setServer("talk.xiaonei.com");
//      StringList ca;
//      ca.push_back( "/path/to/cacert.crt" );
//      j->setCACerts( ca );

      j->logInstance().registerLogHandler( LogLevelDebug, LogAreaAll, this );
      j->connect();
     
    }

    virtual void onConnect()
    {
//      printf( "connected!!!\n" );
    	iLog.Write(_L("connected!!!\n")) ;
    	
    }

    virtual void onDisconnect( ConnectionError e )
    {
//      printf( "message_test: disconnected: %d\n", e );
    	iLog.WriteFormat(_L8("message_test: disconnected: %d\n"),e); 
      if( e == ConnAuthenticationFailed )
    	  iLog.WriteFormat(_L8("auth failed. reason: %d\n"),j->authError()); 
    }

    virtual bool onTLSConnect( const CertInfo& info )
    {
      time_t from( info.date_from );
      time_t to( info.date_to );

//      printf( "status: %d\nissuer: %s\npeer: %s\nprotocol: %s\nmac: %s\ncipher: %s\ncompression: %s\n"
//              "from: %s\nto: %s\n",
//              info.status, info.issuer.c_str(), info.server.c_str(),
//              info.protocol.c_str(), info.mac.c_str(), info.cipher.c_str(),
//              info.compression.c_str(), ctime( &from ), ctime( &to ) );
      return true;
    }

    virtual void handleMessage( const Message& msg, MessageSession * /*session*/ )
    {
//      printf( "type: %d, subject: %s, message: %s, thread id: %s\n", msg.subtype(),
//              msg.subject().c_str(), msg.body().c_str(), msg.thread().c_str() );
      TPtrC8 subject(reinterpret_cast<const TUint8*>(msg.subject().c_str()));
      TPtrC8 body(reinterpret_cast<const TUint8*>(msg.body().c_str()));
      TPtrC8 thread(reinterpret_cast<const TUint8*>(msg.thread().c_str()));
//      HBufC* subU=StrUtil::ConvertToUnicode(subject);
//      HBufC* bodyU=StrUtil::ConvertToUnicode(body);
//      HBufC* threadU=StrUtil::ConvertToUnicode(thread);
//      if(subU==NULL)
//    	  subU=KNullDesC().AllocL();
//      if(bodyU==NULL)
//    	  bodyU=KNullDesC().AllocL();
//      if(threadU==NULL)
//    	  threadU=KNullDesC().AllocL();
      iLog.WriteFormat(_L("type: %d"),
    		  msg.subtype());
      iLog.Write(subject);
      iLog.Write(body);
      iLog.Write(thread);
//      delete subU,bodyU,threadU;
      
      std::string re = "You said:\n> " + msg.body() + "\nI like that statement.";
      std::string sub;
      if( !msg.subject().empty() )
        sub = "Re: " +  msg.subject();

      m_messageEventFilter->raiseMessageEvent( MessageEventDisplayed );

      m_messageEventFilter->raiseMessageEvent( MessageEventComposing );
      m_chatStateFilter->setChatState( ChatStateComposing );

      m_session->send( re, sub );
      j->rosterManager()->fill();
      if( msg.body() == "quit" )
        j->disconnect();
    }

    virtual void handleMessageEvent( const JID& from, MessageEventType event )
    {
//      printf( "received event: %d from: %s\n", event, from.full().c_str() );
    	TPtrC8 ptr((const TUint8*)from.full().c_str(),from.full().length());
    	iLog.WriteFormat(_L8("received state: %d from: %s\n"),event, ptr);  
    }

    virtual void handleChatState( const JID& from, ChatStateType state )
    {
//      printf( "received state: %d from: %s\n", state, from.full().c_str() );
      TPtrC8 ptr((const TUint8*)from.full().c_str(),from.full().length());
      iLog.WriteFormat(_L8("received state: %d from: %s\n"),state, ptr);    
    }

    virtual void handleMessageSession( MessageSession *session )
    {
//      printf( "got new session\n");
      iLog.Write(_L("got new session\n")) ;
      // this example can handle only one session. so we get rid of the old session
      j->disposeMessageSession( m_session );
      m_session = session;
      m_session->registerMessageHandler( this );
      delete m_messageEventFilter;
      delete m_chatStateFilter;
      m_messageEventFilter = new MessageEventFilter( m_session );
      m_messageEventFilter->registerMessageEventHandler( this );
      m_chatStateFilter = new ChatStateFilter( m_session );
      m_chatStateFilter->registerChatStateHandler( this );
    }

    virtual void handleLog( LogLevel level, LogArea area, const std::string& message )
    {
//      printf("log: level: %d, area: %d, %s\n", level, area, message.c_str() );
    	if(message.c_str()==NULL)
    		return;
    	TPtrC8 ptr(reinterpret_cast<const TUint8*>(message.c_str()));
      iLog.WriteFormat(_L("log: level: %d, area: %d"),level, area);  
      iLog.Write(ptr);

    }

  private:
    Client *j;
    MessageSession *m_session;
    MessageEventFilter *m_messageEventFilter;
    ChatStateFilter *m_chatStateFilter;
    RFileLogger iLog; 
};
#endif
